#![allow(dead_code)]
// 来自外部实现的中断打开关闭函数
// 目前的版本并不支持多核心的处理器
extern "C" {
    pub fn rt_hw_interrupt_disable() -> u32;
    pub fn rt_hw_interrupt_enable(data: u32);
}

use core::cell::UnsafeCell;
use core::ops::{Deref, DerefMut};
use alloc::fmt;

unsafe impl<T: ?Sized + Send> Send for KMutex<T> {}
unsafe impl<T: ?Sized + Send> Sync for KMutex<T> {}

pub struct KMutex<T: ?Sized> {
    data: UnsafeCell<T>,
}

impl<T> KMutex<T> {
    pub const fn new(t: T) -> Self {
        KMutex {
            data: UnsafeCell::new(t)
        }
    }

    pub fn lock(&self) -> KMutexGuard<T> {
        // 是安全的
        unsafe {
            KMutexGuard {
                __mutex: rt_hw_interrupt_disable(),
                __data: &self.data,
            }
        }
    }
}

impl<T: ?Sized> fmt::Debug for KMutex<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Kernel Mutex")
    }
}


pub struct KMutexGuard<'a, T: ?Sized + 'a> {
    __mutex: u32,
    __data: &'a UnsafeCell<T>,
}

impl<'mutex, T: ?Sized> Deref for KMutexGuard<'mutex, T> {
    type Target = T;
    fn deref(&self) -> &T {
        unsafe {
            &*self.__data.get()
        }
    }
}

impl<'mutex, T: ?Sized> DerefMut for KMutexGuard<'mutex, T> {
    fn deref_mut(&mut self) -> &mut T {
        unsafe {
            &mut *self.__data.get()
        }
    }
}

impl<'a, T: ?Sized> Drop for KMutexGuard<'a, T> {
    fn drop(&mut self) {
        unsafe {
            rt_hw_interrupt_enable(self.__mutex)
        }
    }
}




// thread mutex

unsafe impl<T: ?Sized + Send> Send for TMutex<T> {}
unsafe impl<T: ?Sized + Send> Sync for TMutex<T> {}

pub struct TMutex<T: ?Sized> {
    data: UnsafeCell<T>,
}

pub struct TMutexGuard<'a, T: ?Sized + 'a> {
    __data: &'a UnsafeCell<T>,
}

impl<T> TMutex<T> {
    pub const fn new(t: T) -> Self {
        TMutex {
            data: UnsafeCell::new(t)
        }
    }

    pub fn lock(&self) -> TMutexGuard<T> {
        // 是安全的
        crate::SCHEDULER_LOCK_NESTED.scheduler_lock();
        TMutexGuard {
            __data: &self.data,
        }
    }
}

impl<'mutex, T: ?Sized> Deref for TMutexGuard<'mutex, T> {
    type Target = T;
    fn deref(&self) -> &T {
        unsafe {
            &*self.__data.get()
        }
    }
}

impl<'mutex, T: ?Sized> DerefMut for TMutexGuard<'mutex, T> {
    fn deref_mut(&mut self) -> &mut T {
        unsafe {
            &mut *self.__data.get()
        }
    }
}

impl<'a, T: ?Sized> Drop for TMutexGuard<'a, T> {
    fn drop(&mut self) {
        crate::SCHEDULER_LOCK_NESTED.scheduler_unlock()
    }
}